using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Sudoku.Menu;
using Services;
using Sudoku.GamePlay;
using System.Diagnostics;
using Sudoku.Lang;
using System.IO.IsolatedStorage;
using System.IO;
using System.Xml.Serialization;
using Sudoku.Utilities;

#if !SUDOKU_MASTER
using Microsoft.Advertising.Mobile.Xna;
#endif

namespace Sudoku.StateManagement
{
	public static class StateManager
	{

		static public void Loader(this Game game)
		{
			game.Components.Add(new Loader(game));
		}
		
		static public void StartMenu(this Game game)
		{
			game.Cleanup();
			game.Components.Add(new InputManager(game));
			game.Components.Add(new MainScene(game));
		}

		static public void DifficultyScreen(this Game game)
		{
			game.Cleanup();
			game.Components.Add(new InputManager(game));
			game.Components.Add(new DifficultyScene(game));
		}

		static public void HowtoScreen(this Game game)
		{
			game.Cleanup();

			game.Components.Add(new InputManager(game));
			game.Components.Add(new HowtoScene(game));
		}

		static public void CreditsScreen(this Game game)
		{
			game.Cleanup();

			game.Components.Add(new InputManager(game));
			game.Components.Add(new CreditsScene(game));
		}

		static public void StartLevel(this Game game, Difficulty difficulty)
		{
			game.Cleanup();

			//if is Trial, remove a game
			if (Guide.IsTrialMode) {
				ITrialService trial = (ITrialService)game.Services.GetService(typeof(ITrialService));
				trial.GameUsed();
			}

			// Delete previous save game when we start a new game
			ISaveService saveService = (ISaveService)game.Services.GetService(typeof(ISaveService));
			saveService.ClearSaveData();

			game.Components.Add(new InputManager(game));

			game.Components.Add(new BoardCreator(game, difficulty));
			game.Components.Add(new BoardCreatorScene(game));

		}

		// Same as StartLevel but we put saved board 
		static public void ContinueGame(this Game game, BoardSaveState boardSave)
		{
			game.Cleanup();
	
			game.Components.Add(new InputManager(game));
			
			Board board = new Board(game, boardSave);
			board.OnGridComplete += (Boolean isValid) => game.OnBoardComplete(isValid);

			game.Components.Add(board);
			game.Components.Add(new UIRenderer(game));
			game.Components.Add(new BoardRenderer(game));
		}

		static private void OnBoardComplete(this Game game, bool isValid)
		{
			foreach (GameComponent c in game.Components)
			{
				if (!(c is InputManager)) c.Enabled = false;
			}

			game.Components.Add(new EndGameScreen(game, isValid));

			// Delete previous save game if the game is complete
			if (isValid)
			{
				ISaveService saveService = (ISaveService)game.Services.GetService(typeof(ISaveService));
				saveService.ClearSaveData();
			}
		}

		public static void SelectIntroScreen(this Game game)
		{
			game.Cleanup();

			game.Components.Add(new LogoScreen(game));
		}

		public static bool first_transition = true;
		public static void Cleanup(this Game game)
		{
			TransitionScreen transition = null;
			if (first_transition != true)
				transition = new TransitionScreen(game);

#if !SUDOKU_MASTER
			for (int i = 0; i < game.Components.Count; i++)
			{
				if ( !(game.Components[i] is AdManager) )
				{
					((GameComponent)game.Components[i]).Dispose();
					i--;
				}
			}
#else
			for (int i = 0; i < game.Components.Count; i++)
			{
				((GameComponent)game.Components[i]).Dispose();
				i--;	
			}
			game.Components.Clear();
#endif
			if (first_transition != true)
				game.Components.Add(transition);
			first_transition = false;
		}
	}
}
